home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Software Vault: The Games Collection 1
/
software vault.zip
/
software vault
/
CDR10
/
YICN23.ZIP
/
UNITS
/
ANIMAP.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1993-02-27
|
11KB
|
323 lines
#include "stddefs.h"
#include <stdlib.h>
#include <fstream.h>
#include <string.h>
#include "icon.h"
#include "animap.h"
#include "xlib.h"
#include "actor.h"
inline int rollover(int number, int limit)
{
int temp = number % limit;
temp += (temp < 0) ? limit : 0;
return temp;
// return number & (limit-1);
}
void animapSquare::display(int x, int y, word pageBase, int squareWidth)
{
draw(x, y, pageBase);
if (nextActor)
drawActors(x + thisFrame->picture.width - squareWidth,
y + thisFrame->picture.height - squareWidth, pageBase);
}
void animapSquare::drawActors(int x, int y, word pageBase)
{
animactor * this_actor = nextActor;
while (this_actor != NULL)
{
this_actor->draw(x - this_actor->thisFrame->picture.width + this_actor->squareX,
y - this_actor->thisFrame->picture.height + this_actor->squareY, pageBase);
this_actor = this_actor->nextActor;
}
}
void animapSquare::advance(void)
#define MAXINASQUARE 20
{
static animactor * voodooActors[MAXINASQUARE];
animslave::advance();
animactor ** voodooCounter = &voodooActors[0];
animactor * this_actor = nextActor;
while (this_actor != NULL)
{
*(voodooCounter++) = this_actor;
this_actor = this_actor->nextActor;
}
*voodooCounter = NULL;
voodooCounter = &voodooActors[0];
while (*voodooCounter != NULL)
{
(*voodooCounter)->advance();
++voodooCounter;
}
}
void * animap::isInSquare(int x, int y, byte searchIdentity)
{
x %= (int)(width);
y %= (int)(height);
x += (x < 0) ? width : 0;
y += (y < 0) ? height : 0;
animactor * this_actor = mapData[x][y].nextActor;
while (this_actor != NULL)
{
if (this_actor->myIdentity == searchIdentity)
return(this_actor);
this_actor = this_actor->nextActor;
}
return NULL;
}
animap::animap(int inumIcons, int sqwidth, int iwidth, int iheight)
{
typedef animapSquare * mapptr;
numIcons = inumIcons;
width = iwidth;
height = iheight;
squareWidth = sqwidth;
mapData = new mapptr[width];
for(int widthCounter = 0; widthCounter < width; ++widthCounter)
{
mapData[widthCounter] = new animapSquare[height];
}
iconTable = new animicon[numIcons];
iconNames = new fileNameString[numIcons];
for (int iconCounter = 0; iconCounter < numIcons; ++iconCounter)
{
iconTable[iconCounter].firstFrame =
iconTable[iconCounter].lastFrame =
iconTable[iconCounter].thisFrame = NULL;
strcpy(iconNames[iconCounter], "");
}
}
animap::~animap()
{
for (int widthCounter = 0; widthCounter < width; ++widthCounter)
delete mapData[widthCounter];
delete mapData;
for(widthCounter = 0; widthCounter < numIcons; ++widthCounter)
{
iconTable[widthCounter].animicon::~animicon();
}
delete iconTable;
delete iconNames;
};
animap::animap(char * filename, yakLib * myYakLib)
{
int inumIcons, sqwidth, iwidth, iheight;
ifstream infile(filename, ios::in | ios::binary);
if (!infile) return;
infile >> inumIcons >> sqwidth >> iwidth >> iheight;
typedef animapSquare * mapptr;
numIcons = inumIcons;
width = iwidth;
height = iheight;
squareWidth = sqwidth;
mapData = new mapptr[width];
for(int widthCounter = 0; widthCounter < width; ++widthCounter)
{
mapData[widthCounter] = new animapSquare[height];
}
iconTable = new animicon[numIcons];
iconNames = new fileNameString[numIcons];
for (int iconCounter = 0; iconCounter < numIcons; ++iconCounter)
{
iconTable[iconCounter].firstFrame =
iconTable[iconCounter].lastFrame =
iconTable[iconCounter].thisFrame = NULL;
strcpy(iconNames[iconCounter], "");
}
for (int counter = 0; counter < numIcons; ++counter)
{
infile >> iconNames[counter];
loadIcon(counter, iconNames[counter], myYakLib);
}
for (word heightCounter = 0; heightCounter < height; ++heightCounter)
{
for (word widthCounter = 0; widthCounter < width; ++widthCounter)
{
infile >> mapData[widthCounter][heightCounter].myIconNumber;
setSquare(widthCounter, heightCounter, mapData[widthCounter][heightCounter].myIconNumber);
}
}
infile.close();
}
void animap::reset()
{
for (int widthCounter = 0; widthCounter < width; ++widthCounter)
for (int heightCounter = 0; heightCounter < height; ++heightCounter)
setSquare(widthCounter, heightCounter, mapData[widthCounter][heightCounter].myIconNumber);
}
void animap::setSquare(word x, word y, byte icon_number)
{
mapData[x][y].myIconNumber = icon_number;
mapData[x][y].myTerrainType = icon_number;
mapData[x][y].thisFrame = iconTable[icon_number].firstFrame;
}
void animap::save(char * filename)
{
ofstream outfile(filename, ios::in | ios::binary);
if (!outfile) return;
outfile << numIcons << '\n' << (int)squareWidth << '\n' << width << '\n' << height << '\n';
for (int counter = 0; counter < numIcons; ++counter)
outfile << iconNames[counter] << '\n';
for (word heightCounter = 0; heightCounter < height; ++heightCounter)
{
for (word widthCounter = 0; widthCounter < width; ++widthCounter)
{
outfile << mapData[widthCounter][heightCounter].myIconNumber;
}
}
outfile.close();
}
void animap::loadIcon(int position, char * filename, yakLib * myYakLib)
{
iconTable[position].addAll(filename, icon::fast, myYakLib);
strcpy(iconNames[position], filename);
}
void animap::load(char * filename)
{
ifstream infile(filename, ios::in | ios::binary);
if (!infile) return;
infile >> numIcons >> squareWidth >> width >> height;
for (int counter = 0; counter < numIcons; ++counter)
{
infile >> iconNames[counter];
loadIcon(counter, iconNames[counter]);
}
for (word heightCounter = 0; heightCounter < height; ++heightCounter)
{
for (word widthCounter = 0; widthCounter < width; ++widthCounter)
{
infile >> mapData[widthCounter][heightCounter].myIconNumber;
setSquare(widthCounter, heightCounter, mapData[widthCounter][heightCounter].myIconNumber);
}
}
infile.close();
}
void animap::draw(int centerx, int centery, int screenx, int screeny, int radx, int rady, word offset)
{
int heightCounter, widthCounter, x, y;
for (heightCounter = -rady; heightCounter <= rady; ++heightCounter)
{
for (widthCounter = -radx; widthCounter <= radx; ++widthCounter)
{
x = (centerx + widthCounter) % (int)(width);
y = (centery + heightCounter) % (int)(height);
x += (x < 0) ? width : 0;
y += (y < 0) ? height : 0;
mapData[x][y].display(screenx + squareWidth*widthCounter - mapData[x][y].thisFrame->picture.width,
screeny + squareWidth*heightCounter - mapData[x][y].thisFrame->picture.height, offset, squareWidth);
}
}
lastMapX = centerx-radx;
lastMapY = centery-rady;
lastScreenX = screenx - squareWidth * radx;
lastScreenY = screeny - squareWidth * rady;
lastDrawWidth = 2*radx+1;
lastDrawHeight = 2*rady+1;
}
void animap::drawXY(int left, int top, int screenLeft, int screenTop, int drawWidth, int drawHeight, word offset)
{
int heightCounter, widthCounter, x, y;
for (heightCounter = 0; heightCounter < drawHeight; ++heightCounter)
{
for (widthCounter = 0; widthCounter < drawWidth; ++widthCounter)
{
x = rollover(left + widthCounter, width);
y = rollover(top + heightCounter, height);
mapData[x][y].display(screenLeft + squareWidth*widthCounter - mapData[x][y].thisFrame->picture.width,
screenTop + squareWidth*heightCounter - mapData[x][y].thisFrame->picture.height, offset, squareWidth);
}
}
lastMapX = left;
lastMapY = top;
lastScreenX = screenLeft;
lastScreenY = screenTop;
lastDrawWidth = drawWidth;
lastDrawHeight = drawHeight;
}
int max(int val1, int val2) {return((val1 > val2) ? val1 : val2);};
void animap::advance()
{
int heightCounter, widthCounter, x, y;
for (heightCounter = 0; heightCounter < height; ++heightCounter)
for (widthCounter = 0; widthCounter < width; ++widthCounter)
mapData[widthCounter][heightCounter].advance();
}
void animap::show(int centerx, int centery, int screenx, int screeny, int radx, int rady, word offset)
{
draw(centerx, centery, screenx, screeny, radx, rady, offset);
advance();
}
void animap::showXY(int left, int top, int screenLeft, int screenTop, int width, int height, word offset)
{
drawXY(left, top, screenLeft, screenTop, width, height, offset);
advance();
}
void animap::smartRefresh(int left, int top, word offset)
{
int heightCounter, widthCounter, x, y, oldX, oldY;
int xCounter, yCounter;
for (heightCounter = 0; heightCounter < lastDrawHeight; ++heightCounter)
for (widthCounter = 0; widthCounter < lastDrawWidth; ++widthCounter)
{
x = rollover(left + widthCounter, width);
y = rollover(top + heightCounter, height);
oldX = rollover(lastMapX + widthCounter, width);
oldY = rollover(lastMapY + heightCounter, height);
mapData[x][y].refresh = (mapData[x][y].refresh == 3) ? 2 : ((mapData[x][y].refresh == 2) ? 1 : 0);
if (mapData[x][y].thisFrame != mapData[oldX][oldY].thisFrame->nextFrame)
mapData[x][y].refresh = 1;
if (mapData[x][y].nextActor || mapData[oldX][oldY].nextActor)
{
mapData[x][y].refresh=1;
mapData[rollover(x-1, width)][y].refresh =1;
mapData[x][rollover(y-1, height)].refresh =1;
mapData[rollover(x-1,width)][rollover(y-1,height)].refresh =1;
}
}
for (heightCounter = 0; heightCounter < lastDrawHeight; ++heightCounter)
{
for (widthCounter = 0; widthCounter < lastDrawWidth; ++widthCounter)
{
x = rollover(left + widthCounter, width);
y = rollover(top + heightCounter, height);
oldX = rollover(lastMapX + widthCounter, width);
oldY = rollover(lastMapY + heightCounter, height);
if (mapData[x][y].refresh)
mapData[x][y].display(lastScreenX + squareWidth*widthCounter - mapData[x][y].thisFrame->picture.width,
lastScreenY + squareWidth*heightCounter - mapData[x][y].thisFrame->picture.height, offset, squareWidth);
}
}
lastMapX = left;
lastMapY = top;
}
void animap::randomize()
{
for (int heightCounter = 0; heightCounter < height; ++heightCounter)
for (int widthCounter = 0; widthCounter < width; ++widthCounter)
setSquare(widthCounter, heightCounter, random(numIcons));
}